package com.lonely.fx;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @date: 2022-07-19 10:29
 * @author: ztkj-hzb
 * @description: 滑块
 **/
public class SliderSettingMain extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    /**
     *
     */
    @Override
    public void start(Stage primaryStage) throws Exception {

        HBox hBox = new HBox();

        Slider slider = new Slider();
        slider.setPrefWidth(400);
        slider.setPrefHeight(60);
        slider.setStyle("-fx-background-color: pink");

        //设置最小值
        slider.setMin(0);

        //设置最大值
        slider.setMax(100);

        //设置当前值
        slider.setValue(50);

        //显示刻度标签
        slider.setShowTickLabels(true);

        //显示刻度线
        slider.setShowTickMarks(true);

        //设置每个刻度的距离
        slider.setMajorTickUnit(10);

        //是否应始终与刻度线对齐
        slider.setSnapToTicks(true);

        //点击滑道的时候移动的距离
        slider.setBlockIncrement(5);

        //按blockIncrement递减值，以最大值为界。如果最大值小于或等于最小值，则此方法不执行任何操作
        slider.decrement();

        //设置方向，默认水平，可以设置为垂直
        //slider.setOrientation(Orientation.VERTICAL);

        //事件
        slider.valueProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                System.out.println("newValue：" + newValue);
            }
        });

        //练习： 让滑块动起来
        SliderTask sliderTask = new SliderTask();
        //设置延时1秒后执行任务
        sliderTask.setDelay(Duration.seconds(1));
        //设置每次执行的间隔事件为50毫秒
        sliderTask.setPeriod(Duration.millis(50));
        //启动任务
        sliderTask.start();

        //设置任务的值变化监听
        sliderTask.valueProperty().addListener((observable, oldValue, newValue) -> {

            if (newValue == null) {
                return;
            }

            if (newValue > slider.getMax()) {
                System.out.println("到达最大值，结束任务");
                sliderTask.cancel();
            }

            slider.setValue(newValue);

        });


        hBox.getChildren().addAll(slider);
        primaryStage.setScene(new Scene(hBox));
        primaryStage.setWidth(600);
        primaryStage.setHeight(500);
        primaryStage.show();
    }


    private class SliderTask extends ScheduledService<Integer> {

        AtomicInteger atomicInteger = new AtomicInteger(0);

        /**
         *
         */
        @Override
        protected Task<Integer> createTask() {
            return new Task<Integer>() {
                /**
                 *
                 */
                @Override
                protected Integer call() throws Exception {
                    return atomicInteger.incrementAndGet();
                }

                /**
                 * 第一种方法：重新updateValue,在这里设置组件的value值，但是需要把组件传入来
                 * 第二种方法，不需要重写，只用在外界任务对象监听value的变化，会把call()方法返回的值传入到value变化的监听中
                 */
                @Override
                protected void updateValue(Integer value) {
                    //该行代码不能去，否则触发不了外界的value值切换监听
                    super.updateValue(value);
                }
            };
        }
    }


}
